ViewBar = function ($, opts) {
    $ = typeof ($) == 'string' ? document.querySelectorAll($) : $;

    var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
    var original, def = {
        tools: ['in', 'out', 'one', 'left', 'right'],
        scale: 0.1,
        rotate: 90
    };

    var style = function (ele, attr) {
        var s = ele.currentStyle ? ele.currentStyle[attr] : document.defaultView.getComputedStyle(ele, null)[attr];
        return Number(s.replace('px', ''));
    };

    opts = _extends(def, opts);

    if (opts.rotate % 90 != 0) {
        alert("暂不支持此角度旋转");
        return;
    }

    var sg = function (obj, k, $1, $2, $3) {
        Object.defineProperty(_.props, $2, {
            get: function () {
                return _.props['_' + $2];
            },
            set: function (v) {
                _.props['_' + $2] = v;
                obj[k] = $1 + v + $3;
            }
        });

    }

    var _ = {
        view: {},
        init(ele) {
            opts.maxX = style(ele, 'width'), opts.maxY = style(ele, 'height');

            var props = ele.querySelectorAll("[data-prop]");
            for (var i = 0; i < props.length; i++) {
                var ds = props[i].dataset;
                if (!ds) { continue; }

                props[i].className += 'view_' + ds.prop;
                _.view[ds.prop] = props[i];
                if (!ds.style) { continue; }

                var obj = JSON.parse(ds.style);
                for (var k in obj) {
                    obj[k].replace(/(.*)\$(\w+)\$(.*)/g, function (s2, $1, $2, $3) {
                        $1 = ($1 || ''), $3 = ($3 || '');
                        var so = props[i].style;
                        sg(so, k, $1, $2, $3);
                        so[k] = $1 + _.props[$2] + $3;
                    });
                }
            }

            _.view.drag = _extends(document.createElement('img'), { src: opts.src, className: 'view_drag' });

            _.view.rotate.appendChild(_.view.drag);

            for (var i = 0; i < opts.tools.length; i++) {
                var key = opts.tools[i], t = _.props.tools[key],
                    tool = _extends(document.createElement('span'), {
                        className: 'view_' + key,
                        title: t[0]
                    });

                tool.dataset.op = t[2];

                _.events.add(tool, 'click', _.methods[t[1]]);
                _.view.tools.appendChild(tool);
            }

            for (var k in _.view) {
                var events = _.events[k];
                for (var e in events) {
                    _.events.add(_.view[k], e, events[e]);
                }
            }
        },
        props: {
            _rotate: 0,
            _scale: 1,
            tools: {
                'in': ['放大', 'scale', '+' + opts.scale],
                'out': ['缩小', 'scale', '-' + opts.scale],
                'one': ['1:1', 'one'],
                'left': ['左转' + opts.rotate + '°', 'rotate', '-' + opts.rotate],
                'right': ['右转' + opts.rotate + '°', 'rotate', '+' + opts.rotate]
            }
        },
        events: {
            box: {
                mousedown(e) {
                    var _box = _.events.box;
                    _.view.drag.dataset.isDrag = 1;

                    _.props.point = {
                        x: e.pageX - _.props.left,
                        y: e.pageY - _.props.top
                    };

                    _box.mousemove(e);

                    _.events.add(document, 'mousemove', _box.mousemove);
                    _.events.add(document, 'mouseup', _box.mouseup);

                    e.preventDefault();
                },
                mousemove(e) {
                    if (_.view.drag.dataset.isDrag) {
                        if (e.movementX == 0 && e.movementY == 0) {
                            return false;
                        }

                        _.props.left = e.pageX - _.props.point.x;
                        _.props.top = e.pageY - _.props.point.y;
                    }
                },
                mouseup(e) {
                    var _box = _.events.box;
                    _.view.drag.dataset.isDrag = '';
                    _.events.remove(document, 'mousemove', _box.mousemove);
                    _.events.remove(document, 'mouseup', _box.mouseup);
                    e.preventDefault();
                }
            },

            drag: {
                load() {
                    original = { width: this.width, height: this.height, dif: (this.height - this.width) / 2 };
                    var rotate = _.props.rotate,
                        rotate_index = rotate / opts.rotate;

                    if (opts.maxX / original.width >= opts.maxY / original.height) {
                        _.props.scale = opts.maxY / original.height;
                    } else {
                        _.props.scale = opts.maxX / original.width;
                    }

                    if (rotate_index % 2 == 1) {
                        _.props.width = original.height;
                        _.props.height = original.width;
                    } else {
                        _.props.width = original.width;
                        _.props.height = original.height;
                    }

                    if (rotate_index == 0) {
                        _.props.left = (opts.maxX - original.width * _.props.scale) / 2;
                        _.props.top = (opts.maxY - original.height * _.props.scale) / 2;
                    } else if (rotate_index == 1) {
                        _.props.left = (opts.maxX - original.height * _.props.scale) / 2;
                        _.props.top = (opts.maxY - original.width * _.props.scale) / 2;

                        _.props.width2 = original.height;
                        _.props.height2 = original.height;
                    } else if (rotate_index == 2) {
                        _.props.left = (opts.maxX - original.width * _.props.scale) / 2;
                        _.props.top = (opts.maxY - original.height * _.props.scale) / 2;
                    } else {
                        _.props.left = (opts.maxX - original.height * _.props.scale) / 2;
                        _.props.top = (opts.maxY - original.width * _.props.scale) / 2;

                        _.props.width2 = original.width;
                        _.props.height2 = original.width;
                    }
                },
                click() {
                }
            },

            add(ele, event, fun) {
                ele.addEventListener(event, fun);
            },
            adds(ele, events, fun) {
                events.length ?
                    (function () {
                        for (var i in events) {
                            this.add(ele, events[i], fun);
                        }
                    })() :
                    this.add(ele, events, fun);
            },
            remove(ele, event, fun) {
                ele.removeEventListener(event, fun);
            },
            removes(ele, events, fun) {
                events.length ?
                    (function () {
                        for (var i in events) {
                            this.remove(ele, events[i], fun);
                        }
                    })() :
                    this.remove(ele, events, fun);
            }
        },
        methods: {
            scale() {
                var op = this.dataset.op,
                    rotate = _.props.rotate,
                    rotate_index = rotate / opts.rotate,
                    left = _.props.left,
                    top = _.props.top,
                    width = original.width,
                    height = original.height;
                _.props.scale = new Function('return ' + _.props.scale + op)();

                if (rotate_index == 0) {
                    if (op == "+" + opts.scale) {
                        _.props.left = left - opts.scale * width / 2;
                        _.props.top = top - opts.scale * height / 2;
                    } else {
                        _.props.left = left + opts.scale * width / 2;
                        _.props.top = top + opts.scale * height / 2;
                    }
                } else if (rotate_index == 1) {
                    if (op == "+" + opts.scale) {
                        _.props.left = left - opts.scale * height / 2;
                        _.props.top = top - opts.scale * width / 2;
                    } else {
                        _.props.left = left + opts.scale * height / 2;
                        _.props.top = top + opts.scale * width / 2;
                    }
                } else if (rotate_index == 2) {
                    if (op == "+" + opts.scale) {
                        _.props.left = left - opts.scale * width / 2;
                        _.props.top = top - opts.scale * height / 2;
                    } else {
                        _.props.left = left + opts.scale * width / 2;
                        _.props.top = top + opts.scale * height / 2;
                    }
                } else {
                    if (op == "+" + opts.scale) {
                        _.props.left = left - opts.scale * height / 2;
                        _.props.top = top - opts.scale * width / 2;
                    } else {
                        _.props.left = left + opts.scale * height / 2;
                        _.props.top = top + opts.scale * width / 2;
                    }
                }
            },
            rotate() {
                var op = this.dataset.op;

                _.props.rotate = new Function('return ' + _.props.rotate + op)();

                if (_.props.rotate >= 360) {
                    _.props.rotate -= 360;
                }

                if (_.props.rotate < 0) {
                    _.props.rotate += 360;
                }

                var rotate_index = _.props.rotate / opts.rotate,
                    left = _.props.left, top = _.props.top,
                    width = original.width,
                    height = original.height,
                    dif = original.dif,
                    scale = _.props.scale;

                if (rotate_index == 0) {
                    _.props.width = width;
                    _.props.height = height;

                    _.props.left = left + dif * scale;
                    _.props.top = top - dif * scale;

                    _.props.width2 = width;
                    _.props.height2 = height;

                } else if (rotate_index == 1) {
                    _.props.width = height;
                    _.props.height = width;

                    _.props.left = left - dif * scale;
                    _.props.top = top + dif * scale;

                    _.props.width2 = height;
                    _.props.height2 = height;

                } else if (rotate_index == 2) {
                    _.props.width = width;
                    _.props.height = height;

                    _.props.left = left + dif * scale;
                    _.props.top = top - dif * scale;

                    _.props.width2 = width;
                    _.props.height2 = height;

                } else {
                    _.props.width = height;
                    _.props.height = width;

                    _.props.left = left - dif * scale;
                    _.props.top = top + dif * scale;

                    _.props.width2 = width;
                    _.props.height2 = width;
                }

                if (rotate_index % 2 == 1) {
                    _.props.width = height;
                    _.props.height = width;
                }
            },
            one() {
                _.props.scale = 1;
            }
        }
    };

    $.length ? (function () {
        for (var i = 0; i < $.length; i++) {
            _.init($[i]);
        }
    })() : _.init($);
}